package com.mdinfo.base.utils;

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.mdinfo.base.common.bean.MemberInfo;
import com.mdinfo.base.component.SpringFactory;
import com.mdinfo.base.constant.MemberConstant;
import com.mdinfo.base.exception.OtherLoginException;
import org.apache.commons.lang3.time.DateUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.UUID;

/**
 * Created by Administrator on 2017/12/5.
 */
public class SystemUtil {

    private static final ThreadLocal<MemberInfo> info = new ThreadLocal<>();

    /**
     * 创建一个token
     * 模拟session的方法,默认有效时间30分钟,每次访问会重新刷新时间
     * 包含自定义参数tokenId
     */
    public static String createToken(MemberInfo memberInfo){

        //记录当前登录时间
        Date loginDate = new Date();
        Long loginTime = loginDate.getTime();
        memberInfo.setLoginTime(loginTime);

        Algorithm algorithm = null;
        try {
            algorithm = Algorithm.HMAC256(MemberConstant.secret);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String token = JWT.create()
                .withClaim("memberId",memberInfo.getMemberId())
                .withClaim("loginTime",loginTime)
//                .withExpiresAt(DateUtils.addHours(loginDate,2))
                .sign(algorithm);

        //把用户信息保存到redis中,有效时间30分钟,每次请求会刷新有效时间
        JedisPool pool = SpringFactory.getBean(JedisPool.class);
        Jedis jedis = pool.getResource();
        String key = MemberConstant.memberToken + "." + memberInfo.getMemberId();
        jedis.setex(key,1800,JSON.toJSONString(memberInfo));
        jedis.close();
        return token;
    }

    /**
     * 验证token
     */
    public static void validate(String token,String path){

        String memberIdStr = null;
        Long loginTime = null;
        try {
            Algorithm algorithm = Algorithm.HMAC256(MemberConstant.secret);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            Claim claim = jwt.getClaim("memberId");
            memberIdStr = String.valueOf(claim.asInt());
            loginTime = jwt.getClaim("loginTime").asLong();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        //通过result去redis中查找对应的memberInfo
        JedisPool pool = SpringFactory.getBean(JedisPool.class);
        Jedis jedis = pool.getResource();
        String key = MemberConstant.memberToken + "." + memberIdStr;
        String s = jedis.get(key);

        MemberInfo memberInfo = JSON.parseObject(s, MemberInfo.class);

        //请求url不是定时请求
        if(!path.equals("/sys/member/online")){
            //刷新缓存时间
            jedis.expire(key,1800);
        }
        jedis.close();


        //redis中没有用户信息.
        if(memberInfo==null){
            throw new TokenExpiredException("找不到用户信息");
        }
        //redis中的登录时间大于token中的登录时间.表示用户在其他地方登录过
        if(memberInfo.getLoginTime().longValue()>loginTime.longValue()){
            throw new OtherLoginException("登录时间不一致");
        }
        info.set(memberInfo);
    }

    /**
     * 获取当前用户信息
     */
    public static MemberInfo getInfo(){
        MemberInfo memberInfo = info.get();
        if(memberInfo==null){
            System.out.println("获取不到当前用户信息");
            throw new TokenExpiredException("找不到用户信息");
        }
        return memberInfo;
    }
}
